# _*_ coding:utf-8 _*_
import os

import requests
from requests import Response

from Logs.log_handle import get_log
from tools.allure_step import allure_step
from tools.request_utils.after_handle_utils import after_extract
from tools.request_utils.cases_global_variables import GLOBAL_VARS
from tools.request_utils.pre_handle_utils import RequestPreDataHandle

log = get_log(os.path.split(__file__)[-1])


class BaseRequest:
    _session = None

    @classmethod
    def get_session(cls):
        """获取或创建一个 requests 会话，用于复用连接。"""
        if cls._session is None:
            cls._session = requests.Session()
        return cls._session

    @classmethod
    def send_request(cls, case: dict) -> tuple[Response, list[str] | None]:
        """
        根据用例数据处理并发送 HTTP 请求。

        :param case: 每一个用例的内容（字典）
        :return: 响应对象
        """
        log.info(f"开始执行用例：{case.get('title')}")
        req_data = RequestPreDataHandle(case).to_request_data

        res = cls.send_api(
            url=req_data["url"],
            method=req_data["method"],
            pk=req_data["pk"],
            header=req_data.get("header"),
            data=req_data.get("data"),
            file=req_data.get("file")
        )
        allure_step('当前全局变量', GLOBAL_VARS)
        extract = after_extract(res, req_data.get("extract"))
        cls._log_response(res)
        return res, extract

    @classmethod
    def send_api(cls, url, method, pk, header=None, data=None, file=None) -> Response:
        """
        发送 HTTP 请求。

        :param method: 请求方法
        :param url: 请求 URL
        :param pk: 参数关键字类型（params, data, json）
        :param header: 请求头信息
        :param data: 请求数据
        :param file: 文件对象
        :return: 响应对象
        """
        session = cls.get_session()
        pk = pk.lower()
        request_args = {"method": method, "url": url, "headers": header}

        if pk == 'params':
            request_args["params"] = data
        elif pk == 'data':
            request_args["data"] = data
            request_args["files"] = file
        elif pk == 'json':
            request_args["json"] = data
            request_args["files"] = file
        else:
            raise ValueError('pk 可选关键字为 params, json, data')

        return session.request(**request_args)

    @staticmethod
    def _log_response(res: Response):
        """记录响应数据，便于调试和追踪。"""
        try:
            response_data = res.json()
        except ValueError:
            response_data = res.text

        log.info(f'请求响应数据: {response_data}')
        allure_step('请求响应数据', response_data)
